//
//  LBTransitionManager.m
//  TEXT
//
//  Created by mac on 2025/3/30.
//  Copyright © 2025 刘博. All rights reserved.
//

#import "LBTransitionManager.h"
#import <UIKit/UIKit.h>
#import "LBTransitionInteractivePopLinearAnimation.h"

@interface LBTransitionManager () <UINavigationControllerDelegate,
UIViewControllerAnimatedTransitioning,
UIViewControllerInteractiveTransitioning>

@property (nonatomic, strong) LBTransitionInteractivePopLinearAnimation *currentInteractiveAnimation;

@property (nonatomic, weak) UIPanGestureRecognizer *currentPanGestureRecognizer;

@property (nonatomic, strong) id <UIViewControllerContextTransitioning> transitionContext;

@end

@implementation LBTransitionManager

+ (instancetype)shareManager
{
    static dispatch_once_t onceToken;
    static LBTransitionManager *shareManager = nil;
    dispatch_once(&onceToken, ^{
        shareManager = [[self alloc] init];
    });
    return shareManager;;
}

- (UIPanGestureRecognizer *)addPanGestureRecognizerToViewControllerIfNeeded:(UIViewController *)viewController {
    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    [viewController.view addGestureRecognizer:panGestureRecognizer];
    return panGestureRecognizer;
}

#pragma mark - UINavigationControllerDelegate

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    
}

- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                                   interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>)animationController {
    return self;
}

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                            animationControllerForOperation:(UINavigationControllerOperation)operation
                                                         fromViewController:(UIViewController *)fromVC
                                                           toViewController:(UIViewController *)toVC {
        return self;
}

#pragma mark - UIViewControllerAnimationTransitioning

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
    NSTimeInterval transitionDuration = 0.4;
    
    if ([self.currentInteractiveAnimation respondsToSelector:@selector(transitionDuration)]) {
        transitionDuration = [self.currentInteractiveAnimation transitionDuration];
    }
    
    return transitionDuration;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
      UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
}

#pragma mark - UIViewControllerInteractiveTransitioning

- (void)startInteractiveTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    NSLog(@"ttttttt startInteractiveTransition, current pan: %@", self.currentPanGestureRecognizer);
    
    [self updateViewsInteractionWithTransitionContext:transitionContext isEnabled:NO];

    id<LBTransitionAnimationProtocol> animation = [[LBTransitionInteractivePopLinearAnimation alloc] init];
    
    [animation prepareTransitionWithTransitionContext:transitionContext];

    if (self.currentPanGestureRecognizer == nil) {
        [animation finishTransitionIsCancel:YES completion:^(BOOL finished, BOOL isCancel, id<UIViewControllerContextTransitioning>  _Nonnull transitionContext) {
            [self finishInteractiveTransitionWithTransitionContext:transitionContext isCancel:isCancel isAnimationFinished:finished];
            
            [self updateViewsInteractionWithTransitionContext:transitionContext isEnabled:YES];
        }];
    } else {
        self.currentInteractiveAnimation = animation;
    }
}

#pragma mark - action

- (void)handlePan:(id)sender {
    if (![sender isKindOfClass:[UIPanGestureRecognizer class]]) return;
    
    UIPanGestureRecognizer *panGestureRecognizer = sender;
    CGPoint velocity = [panGestureRecognizer velocityInView:panGestureRecognizer.view.superview];
    CGPoint translation = [panGestureRecognizer translationInView:panGestureRecognizer.view.superview];
    CGFloat percentComplete = [self percentCompleteWithTranslation:translation];
    UIResponder *nextResponder = panGestureRecognizer.view.nextResponder;
    switch (panGestureRecognizer.state) {
        case UIGestureRecognizerStateBegan: {
            NSLog(@"ttttttt pan pop state began");
            
            CGFloat velocityX = velocity.x;
            CGFloat velocityY = velocity.y;
            
            if (velocityX == 0.0) {
                panGestureRecognizer.enabled = NO;
                panGestureRecognizer.enabled = YES;
                return;
            }
            self.currentPanGestureRecognizer = panGestureRecognizer;
            UINavigationController *navigationController = self.navigationController;
            id<UINavigationControllerDelegate> navigationControllerDelegate = navigationController.delegate;
            navigationController.delegate = self;
            NSLog(@"LIVDetailTransitionManager navigationControllerDelegate: %@", navigationController.delegate);
            [navigationController popViewControllerAnimated:YES];
            navigationController.delegate = navigationControllerDelegate;
        }
            break;
        case UIGestureRecognizerStateChanged: {
            NSLog(@"这里的animation %@", self.currentInteractiveAnimation);
            BOOL finishInstantly = [self.currentInteractiveAnimation updateTransitionWithPercentComplete:percentComplete translation:translation];
            
            if (finishInstantly) {
                self.currentPanGestureRecognizer.state = UIGestureRecognizerStateEnded;
            }
        }
            break;
        
        case UIGestureRecognizerStateCancelled:
              case UIGestureRecognizerStateFailed: {
                  NSLog(@"ttttttt pan pop state cancelled, failed, started: %@", self.currentInteractiveAnimation);

                  self.currentPanGestureRecognizer = nil;

                  [self.currentInteractiveAnimation finishTransitionIsCancel:YES completion:^(BOOL finished, BOOL isCancel, id<UIViewControllerContextTransitioning> transitionContext) {
                      [self finishInteractiveTransitionWithTransitionContext:transitionContext isCancel:isCancel isAnimationFinished:finished];
                  }];
              } break;
            
        case UIGestureRecognizerStateEnded: {
            BOOL isTransitionMadeProgress = percentComplete > 0.1;
            BOOL isPanRight = velocity.x > 0.0;
            BOOL shouldComplete = NO;
            shouldComplete = (isTransitionMadeProgress && isPanRight) || velocity.x > 100.0;

            NSLog(@"ttttttt pan pop state end: %d, %d, %d, %@", isTransitionMadeProgress, isPanRight, shouldComplete, self.currentInteractiveAnimation);
            self.currentPanGestureRecognizer = nil;
            __weak typeof(self) weakSelf = self;
            [self.currentInteractiveAnimation finishTransitionIsCancel:!shouldComplete completion:^(BOOL finished, BOOL isCancel, id<UIViewControllerContextTransitioning> transitionContext) {
                [self finishInteractiveTransitionWithTransitionContext:transitionContext isCancel:isCancel isAnimationFinished:finished];
                
                [self updateViewsInteractionWithTransitionContext:transitionContext isEnabled:YES];
            }];
        } break;
        default:
            break;
    }
}

- (CGFloat)percentCompleteWithTranslation:(CGPoint)translation {
    CGFloat translationX = translation.x;
    CGFloat translationXRangeMin = 0.0;
    CGFloat translationXRangeMax = 200.0;
    
    if (translationX < translationXRangeMin) {
        return 0.0;
    } else if (translationX > translationXRangeMax) {
        return 1.0;
    } else {
        return (translationX - translationXRangeMin) / (translationXRangeMax - translationXRangeMin);
    }
}

- (void)finishInteractiveTransitionWithTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext isCancel:(BOOL)isCancel isAnimationFinished:(BOOL)isAnimationFinished {
    NSLog(@"ttttttt finish interactive transition: %d, %d", isCancel, isAnimationFinished);
        
    id<LBTransitionAnimationProtocol> currentInteractiveAnimation = self.currentInteractiveAnimation;
    self.currentInteractiveAnimation = nil;

    if (isCancel) {
        [transitionContext cancelInteractiveTransition];
    } else {

        [transitionContext finishInteractiveTransition];
    }
    
    [transitionContext completeTransition:!isCancel];
}

- (void)updateViewsInteractionWithTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext isEnabled:(BOOL)isEnabled {
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    fromViewController.view.userInteractionEnabled = isEnabled;
    toViewController.view.userInteractionEnabled = isEnabled;
}

@end
